package com.zjh.mf.mfcorelib.util;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串相关工具类
 */
public class StringUtils {

    private StringUtils() {
        throw new UnsupportedOperationException("u can't instantiate me --StringUtils");
    }

    /**
     * 字符串拼接,线程安全
     */
    public static String buffer(String... array) {
        StringBuffer s = new StringBuffer();
        for (String str : array) {
            s.append(str);
        }
        return s.toString();
    }

    /**
     * 字符串拼接,线程不安全,效率高
     */
    public static String builder(String... array) {
        StringBuilder s = new StringBuilder();
        for (String str : array) {
            s.append(str);
        }
        return s.toString();
    }


    /**
     * 判断字符串是否为null或长度为0
     *
     * @param s 待校验字符串
     * @return {@code true}: 空<br> {@code false}: 不为空
     */
    public static boolean isEmpty(CharSequence s) {
        return s == null || s.length() == 0;
    }

    /**
     * 判断字符串是否为null或全为空格
     *
     * @param s 待校验字符串
     * @return {@code true}: null或全空格<br> {@code false}: 不为null且不全空格
     */
    public static boolean isSpace(String s) {
        return (s == null || s.trim().length() == 0);
    }

    /**
     * 判断两字符串是否相等
     *
     * @param a 待校验字符串a
     * @param b 待校验字符串b
     * @return {@code true}: 相等<br>{@code false}: 不相等
     */
    public static boolean equals(CharSequence a, CharSequence b) {
        if (a == b) return true;
        int length;
        if (a != null && b != null && (length = a.length()) == b.length()) {
            if (a instanceof String && b instanceof String) {
                return a.equals(b);
            } else {
                for (int i = 0; i < length; i++) {
                    if (a.charAt(i) != b.charAt(i)) return false;
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 判断两字符串忽略大小写是否相等
     *
     * @param a 待校验字符串a
     * @param b 待校验字符串b
     * @return {@code true}: 相等<br>{@code false}: 不相等
     */
    public static boolean equalsIgnoreCase(String a, String b) {
        return (a == b) || (b != null) && (a.length() == b.length()) && a.regionMatches(true, 0, b, 0, b.length());
    }

    /**
     * null转为长度为0的字符串
     *
     * @param s 待转字符串
     * @return s为null转为长度为0字符串，否则不改变
     */
    public static String null2Length0(String s) {
        return s == null ? "" : s;
    }

    /**
     * 返回字符串长度
     *
     * @param s 字符串
     * @return null返回0，其他返回自身长度
     */
    public static int length(CharSequence s) {
        return s == null ? 0 : s.length();
    }

    /**
     * 首字母大写
     *
     * @param s 待转字符串
     * @return 首字母大写字符串
     */
    public static String upperFirstLetter(String s) {
        if (isEmpty(s) || !Character.isLowerCase(s.charAt(0))) return s;
        return String.valueOf((char) (s.charAt(0) - 32)) + s.substring(1);
    }

    /**
     * 首字母小写
     *
     * @param s 待转字符串
     * @return 首字母小写字符串
     */
    public static String lowerFirstLetter(String s) {
        if (isEmpty(s) || !Character.isUpperCase(s.charAt(0))) return s;
        return String.valueOf((char) (s.charAt(0) + 32)) + s.substring(1);
    }

    /**
     * 反转字符串
     *
     * @param s 待反转字符串
     * @return 反转字符串
     */
    public static String reverse(String s) {
        int len = length(s);
        if (len <= 1) return s;
        int mid = len >> 1;
        char[] chars = s.toCharArray();
        char c;
        for (int i = 0; i < mid; ++i) {
            c = chars[i];
            chars[i] = chars[len - i - 1];
            chars[len - i - 1] = c;
        }
        return new String(chars);
    }

    /**
     * 转化为半角字符
     *
     * @param s 待转字符串
     * @return 半角字符串
     */
    public static String toDBC(String s) {
        if (isEmpty(s)) return s;
        char[] chars = s.toCharArray();
        for (int i = 0, len = chars.length; i < len; i++) {
            if (chars[i] == 12288) {
                chars[i] = ' ';
            } else if (65281 <= chars[i] && chars[i] <= 65374) {
                chars[i] = (char) (chars[i] - 65248);
            } else {
                chars[i] = chars[i];
            }
        }
        return new String(chars);
    }

    /**
     * 转化为全角字符
     *
     * @param s 待转字符串
     * @return 全角字符串
     */
    public static String toSBC(String s) {
        if (isEmpty(s)) return s;
        char[] chars = s.toCharArray();
        for (int i = 0, len = chars.length; i < len; i++) {
            if (chars[i] == ' ') {
                chars[i] = (char) 12288;
            } else if (33 <= chars[i] && chars[i] <= 126) {
                chars[i] = (char) (chars[i] + 65248);
            } else {
                chars[i] = chars[i];
            }
        }
        return new String(chars);
    }

    /**
     * 时间处理
     *
     * @param time
     * @return
     */
    public static String getTimeDay(String time) {
        if (TextUtils.isEmpty(time) || !time.contains("T")) {
            return time;
        }
        return time.substring(0, time.indexOf("T"));
    }

    /**
     * 只取月份和日期
     *
     * @param time
     * @return
     */
    public static String getDay(String time) {
        if (TextUtils.isEmpty(time) || !time.contains("T")) {
            return time;
        }

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
        try {
            Date date = df.parse(time);
            return new SimpleDateFormat("MM-dd", Locale.getDefault()).format(date);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 时间戳转时间
     *
     * @param time
     * @return
     */
    public static String getTimeByNum(long time) {
        if (time > 0) {
            Date date = new Date(time);
            SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd", Locale.getDefault());
            return df.format(date);
        } else {
            return null;
        }
    }

    /**
     * 时间戳转时间2
     *
     * @param time
     * @return
     */
    public static String getTimeByNum2(int time) {
        if (time > 0) {
            Date date = new Date(time);
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
            return df.format(date);
        } else {
            return null;
        }
    }


    /**
     * 时间戳转时间2
     *
     * @param time
     * @return
     */
    public static String getTimeByNum2(long time) {
        if (time > 0) {
            Date date = new Date(time);
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
            return df.format(date);
        } else {
            return null;
        }
    }

    /**
     * 时间戳转时间字符串
     */
    public static String getTimeStrByLong(long time, String type) {
        Date date = new Date(time);
        SimpleDateFormat df = new SimpleDateFormat(type, Locale.getDefault());
        return df.format(date);
    }


    /**
     * 得到到精确到分的时间
     *
     * @param time
     * @return
     */
    public static String getTimeMinute(String time) {
        if (TextUtils.isEmpty(time)) {
            return "";
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
        try {
            Date date = df.parse(time);
            return new SimpleDateFormat("yyyy.MM.dd    HH:mm", Locale.getDefault()).format(date);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 得到YYYY.MM.dd格式时间
     *
     * @param time
     * @return
     */
    public static String getTimeType1(String time) {
        if (TextUtils.isEmpty(time)) {
            return "";
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
        try {
            Date date = df.parse(time);
            return new SimpleDateFormat("yyyy.MM.dd", Locale.getDefault()).format(date);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 转换“yyyy-MM-dd”格式的时间到long
     *
     * @param input
     * @return
     */
    public static long getTimeLong(String input) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
        try {
            Date date = df.parse(input);
            return date.getTime();
        } catch (ParseException e) {
            Log.e("parse error", "转换时间错误：" + input);
            return 0;
        }
    }

    /**
     * 将json时间字符串转换为Date
     *
     * @param input
     * @return
     */
    public static Date JsonTimeToDate(String input) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
        if (input.contains("T"))
            input = input.replace('T', ' ');
        if (input.contains("Z"))
            input = input.replace("Z", "+0000");
        try {
            Date date = df.parse(input);
            return date;
        } catch (ParseException e) {
            Log.e("parse error", "JsonTimeToDate转换时间错误：" + input);
            return null;
        }
    }

    /**
     * 得到剩余秒数
     *
     * @param time
     * @return
     */
    public static long getRemainTime(String time) {
        Date date = JsonTimeToDate(time);
        long currentTime = System.currentTimeMillis();
        long endTime = date.getTime();
        long remainTime = (endTime - currentTime) / 1000;
        if (remainTime < 0) {
            remainTime = 0;
        }
        return remainTime;
    }

    /**
     * 根据服务器时间得到剩余秒数
     *
     * @return
     */
    public static long getRemainTime(String currentTimeStr, String endTimeStr) {
        Date currentDate = JsonTimeToDate(currentTimeStr);
        Date endDate = JsonTimeToDate(endTimeStr);
        long currentTime = currentDate.getTime();
        long endTime = endDate.getTime();
        long remainTime = (endTime - currentTime) / 1000;
        if (remainTime < 0) {
            remainTime = 0;
        }
        return remainTime;
    }

    /**
     * 获取相对时间
     *
     * @param time
     * @return
     */
    public static String getAbsolutelyTime(String time) {
        Date date = JsonTimeToDate(time);
        long publishTime = date.getTime();
        return getAbsolutelyTime(publishTime);
    }

    /**
     * 获取相对时间
     */
    public static String getAbsolutelyTime(long publishTime) {
        long currentTime = System.currentTimeMillis();
        long lastTime = (currentTime - publishTime) / 1000;
        if (lastTime >= 60) {
            int year = (int) (lastTime / (12 * 30 * 24 * 3600));
            if (year != 0) {
                return year + "年前";
            }
            int month = (int) (lastTime / (30 * 24 * 3600));
            if (month != 0) {
                return month + "月前";
            }
            int day = (int) (lastTime / (24 * 3600));
            if (day != 0) {
                return day + "天前";
            }
            int hour = (int) (lastTime / 3600);
            if (hour != 0) {
                return hour + "小时前";
            }
            int minute = (int) (lastTime / 60);
            if (minute != 0) {
                return minute + "分钟前";
            }
        }
        return "刚刚";
    }

    /**
     * 转换时间格式
     */
    public static String turnDateStyle(String dateStr, String oldStyle, String newStyle) {
        if (TextUtils.isEmpty(dateStr))
            return null;

        if (TextUtils.isEmpty(oldStyle)) {
            oldStyle = "yyyy-MM-dd' 'HH:mm:ss";
        }
        SimpleDateFormat df = new SimpleDateFormat(oldStyle, Locale.getDefault());
        try {
            Date date = df.parse(dateStr);
            return new SimpleDateFormat(newStyle, Locale.getDefault()).format(date);
        } catch (ParseException e) {
            return null;
        }
    }


    /**
     * 删除标签和空格
     */
    public static String delHtml(String mobiles) {
        String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
        String regEx_space = "\\s*|\t|\r|\n";//定义空格回车换行符

        //删除html标签
        Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
        Matcher m_html = p_html.matcher(mobiles);
        mobiles = m_html.replaceAll(""); // 过滤html标签

        Pattern p_space = Pattern.compile(regEx_space, Pattern.CASE_INSENSITIVE);
        Matcher m_space = p_space.matcher(mobiles);
        mobiles = m_space.replaceAll(""); // 过滤空格回车标签
        return mobiles;
    }

    /**
     * 判断手机号码
     */
    public static boolean isMobileNO(String mobiles) {
        if (TextUtils.isEmpty(mobiles))
            return false;
        Pattern pattern = Pattern
                .compile("^1\\d{10}$");
        Matcher matcher = pattern.matcher(mobiles);
        return matcher.matches();
    }

    /**
     * 判断是否是邮箱
     *
     * @param email
     * @return
     */
    public static boolean isEmail(String email) {
        Pattern pattern = Pattern
                .compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");
        Matcher matcher = pattern.matcher(email);
        return matcher.matches();
    }

    /**
     * 判断网址
     */
    public static boolean isURL(String url) {

        Pattern httpPtn = Pattern
                .compile("(http://|https://|www){0,1}[^\u4e00-\u9fa5\\s]*?\\.(com|net|cn|me|tw|fr)[^\u4e00-\u9fa5\\s]*");
        return httpPtn.matcher(url).matches();
    }

    /**
     * 转换为两位数字
     *
     * @param num
     * @return
     */
    public static String toTwoNum(long num) {
        DecimalFormat df = new DecimalFormat("00");
        return df.format(num);
    }

    /**
     * 保留一位小数
     *
     * @param num
     * @return
     */
    public static String toOneDec(Object num) {
        DecimalFormat df = new DecimalFormat("0.0");
        return df.format(num);
    }

    /**
     * 保留两位小数
     *
     * @param num
     * @return
     */
    public static String toTwoDec(Object num) {
        DecimalFormat df = new DecimalFormat("0.00");
        return df.format(num);
    }

    /**
     * 保留两位小数签名千分位
     *
     * @param num
     * @return
     */
    public static String toTwoDec2(Object num) {
        DecimalFormat df = new DecimalFormat("###,##0.00");
        return df.format(num);
    }

    /**
     * 保留几位小数位
     *
     * @param num    值
     * @param desNum 小数位数
     * @return
     */
    public static String toDes(Object num, int desNum) {
        String format = "0";
        if (desNum > 0) {
            format += ".";
        }
        for (int i = 0; i < desNum; i++) {
            format += "0";
        }
        DecimalFormat df = new DecimalFormat(format);
        return df.format(num);
    }

    /**
     * String转换
     *
     * @param num 只能是double和float类型
     * @return
     */
    public static String toString(Object num) {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setGroupingUsed(false);
        nf.setMaximumFractionDigits(12);
        return nf.format(num);
    }

    /**
     * String转换
     *
     * @param num 只能是double和float类型
     *            maxDigits 最大小数位
     */
    public static String toString(Object num, int maxDigits) {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setGroupingUsed(false);
        nf.setMaximumFractionDigits(maxDigits);
        return nf.format(num);
    }

    /**
     * 生成随机字符串
     *
     * @param length 表示生成字符串的长度
     */
    public static String getRandomString(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }


    /**
     * bitmap转为base64
     *
     * @param bitmap
     * @return
     */
    public static String bitmapToBase64(Bitmap bitmap) {

        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

                baos.flush();
                baos.close();

                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 千分位
     *
     * @return
     */
    public static String toCurrencyType(Object number, boolean moneyType) {
        if (moneyType) {
            return NumberFormat.getCurrencyInstance().format(number);
        } else {
            return DecimalFormat.getNumberInstance().format(number);
        }
    }


    /**
     * base64转为bitmap
     *
     * @param base64Data
     * @return
     */
    public static Bitmap base64ToBitmap(String base64Data) {
        byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }


    /**
     * 判断输入字符串是否为科学计数法
     */
    public static boolean isENum(String input) {
        if (TextUtils.isEmpty(input)) {
            return false;
        }
        Pattern pattern = Pattern.compile("^((-?\\d+.?\\d*)[Ee]{1}(-?\\d+))$");
        return pattern.matcher(input).matches();
    }

    /**
     * String 转unicode
     *
     * @param str
     * @return
     */
    public static String toUnicode(String str) {
        if (str == null)
            return null;

        StringBuffer unicode = new StringBuffer();
        for (int i = 0; i < str.length(); i++) {
            // 取出每一个字符
            char c = str.charAt(i);
            // 转换为unicode
            unicode.append("\\u" + Integer.toHexString(c));
        }

        return unicode.toString();
    }

    /**
     * 字符串转浮点型
     */
    public static double getDouble(String str) {
        if (TextUtils.isEmpty(str)) {
            return 0;
        }

        int i = 1;
        if (str.startsWith("-")) {
            str = str.replace("-", "");
            i = -1;
        } else if (str.startsWith("+")) {
            str = str.replace("+", "");
        }
        if (str.startsWith(".")) {
            str = str.replace(".", "0.");

        }
        if (str.endsWith(".") || str.endsWith("-") || str.endsWith("+")) {
            str = str.substring(0, str.length() - 1);
        }

        return TextUtils.isEmpty(str) ? 0 : Double.parseDouble(str);
    }

    /**
     * 把中文字符转换为带百分号的浏览器编码
     *
     * @param word
     * @return
     */
    public static String toBrowserCode(String word) {
        final String HEX_STRING = "0123456789ABCDEF";
        byte[] bytes = word.getBytes();

        //不包含中文，不做处理
        if (bytes.length == word.length())
            return word;

        StringBuilder browserUrl = new StringBuilder();
        String tempStr = "";

        for (int i = 0; i < word.length(); i++) {
            char currentChar = word.charAt(i);

            //不需要处理
            if ((int) currentChar <= 256) {

                if (tempStr.length() > 0) {
                    byte[] cBytes = tempStr.getBytes();

                    for (int j = 0; j < cBytes.length; j++) {
                        browserUrl.append('%');
                        browserUrl.append(HEX_STRING.charAt((cBytes[j] & 0xf0) >> 4));
                        browserUrl.append(HEX_STRING.charAt((cBytes[j] & 0x0f) >> 0));
                    }
                    tempStr = "";
                }

                browserUrl.append(currentChar);
            } else {
                //把要处理的字符，添加到队列中
                tempStr += currentChar;
            }
        }
        return browserUrl.toString();
    }

}